from django.shortcuts import render
from django.contrib.auth import authenticate, login
from django.contrib.auth.backends import ModelBackend
from django.views.generic.base import View
from django.db.models import Q
from django.contrib.auth.hashers import make_password

# 导入 modal
from .models import UserProfile, EmailVerifyRecord
# 导入 forms
from .forms import LoginForm, RegisterForm, ForgetForm, ModifyPwdForm
# 导入发送邮件
from utils.email_send import send_register_email
# Create your views here.


# 重载 django 的用户认证方法，需要在setting中配置 AUTHENTICATION_BACKENDS
class CustomBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        print("----- 进入自定义的用户认证方法 -----")
        try:
            # Q 是 或者，username == username 或者 username == email
            # 因为 django 储存的密码是密文，所以不能去匹配 password=password
            user = UserProfile.objects.get(Q(username=username)|Q(email=username))
            # django 提供的校验密码的方法
            if user.check_password(password):
                return user
        except Exception as e:
            # 如果验证失败，返回None
            return None


# 登录
class LoginView(View):

    # GET请求返回
    def get(self, request):
        return render(request, "login.html", {})

    # POST请求返回
    def post(self, request):
        # 使用自定义的 form 去校验，用于减少数据库的负担
        login_form = LoginForm(request.POST)
        # 判断数据是否合规
        if login_form.is_valid():
            # 获取请求中的参数
            user_name = request.POST.get("username", "")  # 获取提交上来的用户名，默认为空
            pass_word = request.POST.get("password", "")  # 获取提交上来的密码，默认为空

            # 调用 django 的用户认证
            user = authenticate(username=user_name, password=pass_word)  # django提供的用户验证方法，成功的话会返回user，否则返回 null

            # 调用 django 的登录
            if user is not None:
                if user.is_active:
                    login(request, user)
                    print("----- 用户登录成功 -----")
                    return render(request, "index.html")
                else:
                    return render(request, "login.html", {"msg": "该用户未激活，请留意激活邮件"})
            else:
                return render(request, "login.html", {"msg": "用户账号密码不匹配"})

        else:
            print("----- 用户账号密码不匹配 -----")
            return render(request, "login.html", {"login_form": login_form})


# 注册
class RegisterView(View):

    # GET请求返回
    def get(self, request):
        register_form = RegisterForm()
        return render(request, "register.html", {'register_form': register_form})

    # POST请求返回
    def post(self, request):
        # 使用自定义的 form 去校验，用于减少数据库的负担
        register_form = RegisterForm(request.POST)
        # 判断数据是否合规
        if register_form.is_valid():
            print("----- 提交的信息通过验证 -----")
            # 获取请求中的参数
            user_name = request.POST.get("email", "")  # 获取提交上来的用户名，默认为空
            pass_word = request.POST.get("password", "")  # 获取提交上来的密码，默认为空

            # 判断用户是否已经存在
            if UserProfile.objects.filter(email=user_name):
                print("----- 该用户已存在 -----")
                return render(request, "register.html", {"register_form": register_form, "msg": "该用户已存在"})

            # 实例一个新对象
            user_profile = UserProfile()

            # 为新对象赋值
            user_profile.username = user_name
            user_profile.email = user_name
            user_profile.password = make_password(pass_word)
            user_profile.is_active = False  # 是否激活

            # 保存新用户
            user_profile.save()

            # 发送验证邮件
            send_register_email(user_name, "register")
            return render(request, "login.html")

        else:
            print("----- 提交的信息不合规范 -----")
            return render(request, "register.html", {"register_form": register_form})


# 用户激活
class ActiveUserView(View):

    # GET 请求
    def get(self, request, active_code):
        all_records = EmailVerifyRecord.objects.filter(code=active_code)
        if (all_records):
            for record in all_records:
                email = record.email
                user = UserProfile.objects.get(email=email)
                user.is_active = True
                user.save()
            return render(request, "login.html")
        else:
            return render(request, "active_fail.html")


# 忘记密码
class ForgetPwdView(View):
    # GET 请求
    def get(self, request):
        forget_form = ForgetForm(request.POST)
        return render(request, "forgetpwd.html", {"forget_form": forget_form})

    # POST请求返回
    def post(self, request):
        forget_form = ForgetForm(request.POST)
        if forget_form.is_valid():
            print("----- 提交的信息通过验证 -----")
            email = request.POST.get("email", "")  # 获取提交上来的用户名，默认为空

            # 发送验证邮件
            send_register_email(email, "forget")

            return render(request, "send_success.html")

        else:
            return render(request, "forgetpwd.html", {"forget_form": forget_form})


# 重置密码激活
class ResetUserView(View):

    # GET 请求
    def get(self, request, active_code):
        all_records = EmailVerifyRecord.objects.filter(code=active_code)
        if (all_records):
            for record in all_records:
                email = record.email
            return render(request, "password_reset.html", {"email": email})
        else:
            return render(request, "login.html")


# 重置密码
class ModifyPwdView(View):

    # GET 请求
    def get(self, request):
        pass

     # POST请求返回
    def post(self, request):
        modify_form = ModifyPwdForm(request.POST)
        if modify_form.is_valid():
            print("----- 提交的信息通过验证 -----")
            # 获取请求中的参数
            pwd1 = request.POST.get('password1', "")
            pwd2 = request.POST.get('password2', "")
            email = request.POST.get('email', "")

            if pwd1 != pwd2:
                return render(request, "password_reset.html", {"email": email, "msg": "密码不一致"})

            user = UserProfile.objects.get(email=email)
            user.password = make_password(pwd1)
            user.save()

            return render(request, "login.html")

        else:
            print("----- 提交的信息未通过验证 -----")
            email = request.POST.get('email', "")
            return render(request, "password_reset.html", {"email": email, "modify_form": modify_form})
